import * as fs from 'fs'
import * as path from 'path'

/**
 * 检查指定路径的文件或文件夹是否存在
 * @param targetPath 需要检查的文件或文件夹路径
 * @returns Promise<boolean> 返回一个Promise，解析为true表示存在，false表示不存在
 */
export const exists = async (targetPath: string): Promise<boolean> => {
  try {
    await fs.promises.access(targetPath)
    return true
  } catch {
    return false
  }
}

/**
 * 确保目录存在（如果不存在则会创建）
 * 用法：传入需要检查或创建的目录路径，例如：ensureDirectoryExists('/path/to/directory');
 */
export const ensureDirectoryExists = async (
  directory: string,
): Promise<void> => {
  try {
    await fs.promises.access(directory, fs.constants.F_OK)
  } catch {
    try {
      await fs.promises.mkdir(directory, { recursive: true })
    } catch (error) {
      console.error(`Failed to create upload directory: ${directory}`, error)
      throw error
    }
  }
}

/**
 * 移动文件或文件夹到指定路径（如果目标目录不存在则会自动创建）。
 * @param sourcePath 源文件或文件夹路径
 * @param destinationPath 目标文件或文件夹路径
 * @returns Promise<void>
 */
export const moveFile = async (
  sourcePath: string,
  destinationPath: string,
): Promise<void> => {
  try {
    // 检查源文件/文件夹是否存在
    try {
      await fs.promises.access(sourcePath)
    } catch (error) {
      throw new Error(`源路径不存在: ${sourcePath}`)
    }

    // 获取目标目录路径
    const destDir = path.dirname(destinationPath)

    // 检查目标目录是否存在，不存在则创建
    try {
      await fs.promises.access(destDir)
    } catch (error) {
      await fs.promises.mkdir(destDir, { recursive: true })
      console.log(`创建目标目录: ${destDir}`)
    }

    // 执行移动操作
    await fs.promises.rename(sourcePath, destinationPath)
    console.log(`成功移动 ${sourcePath} 到 ${destinationPath}`)
  } catch (error) {
    if (typeof error === 'object' && error !== null && 'message' in error) {
      console.error(
        '移动文件/文件夹失败:',
        (error as { message?: string }).message,
      )
    } else {
      console.error('移动文件/文件夹失败:', error)
    }
  }
}

export const deleteFileOrDir = async (targetPath: string): Promise<void> => {
  try {
    // 检查目标路径是否存在
    await fs.promises.access(targetPath)

    // 删除文件或文件夹
    await fs.promises.rm(targetPath, { recursive: true, force: true })
    console.log(`成功删除: ${targetPath}`)
  } catch (error: NodeJS.ErrnoException | unknown) {
    if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
      console.log(`路径不存在，跳过删除: ${targetPath}`)
    } else {
      console.error('删除失败:', (error as Error).message)
    }
  }
}

/**
 * 删除文件或文件夹
 * @param targetPath 目标路径
 * @returns Promise<void> 删除成功时返回Promise，失败时抛出错误
 */
export const delFile = async (targetPath: string): Promise<void> => {
  try {
    // 检查目标路径是否存在
    await fs.promises.access(targetPath)

    // 删除文件或文件夹
    await fs.promises.rm(targetPath, { recursive: true, force: true })
    console.log(`成功删除: ${targetPath}`)
  } catch (error: NodeJS.ErrnoException | unknown) {
    if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
      throw new Error(`路径不存在，跳过删除: ${targetPath}`)
    } else {
      throw new Error('删除失败')
    }
  }
}
